home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / comm / mail / mailserver10.lha / Mailserver / sys / mailserver < prev    next >
Encoding:
Text File  |  1995-04-08  |  14.7 KB  |  624 lines

  1. /* $VER: Mailserver version 1.0 by D. Ramsey - dom@dynamo.demon.co.uk
  2.    Mailserver (c)1995 D. Ramsey - dom@dynamo.demon.co.uk
  3.    Freely distributable
  4. */
  5.  
  6. call initialise
  7. call startup
  8. call get_listowner
  9. call get_prefs
  10. call get_externals
  11. call who_from
  12. call change_realname
  13. call send_receipt
  14. call process_instructions
  15. call update_log
  16. call clean_up
  17.  
  18. /* Finished */
  19. EXIT
  20.  
  21. /********************************************************************/
  22. :
  23.  /* Initialise variables, wait for other copies of the program to
  24.     finish, then open a lock file to prevent other copies running.*/
  25.  
  26. initialise:
  27.  prefsfile    = 'mailserver:sys/prefs'
  28.  externalsfile= 'mailserver:sys/externals'
  29.  numexternals = 0
  30.  inform       = 'YES'  /* Send mail to list owner when mail received? */
  31.  keeplog      = 'yes'   /* Keep a lofile of incoming requests? */
  32.  receipt      = 'YES'  /* Send a receipt with mail */
  33.  logname      = 'uuspool:mailserver.log'
  34.  mailname     = 'Amiga Mailserver'
  35.  realname     = ''     /* Temp store for user's REALNAME */
  36.  dir_cmd      = 'list'
  37.  dir_cmd_opts = ' '
  38.  tmpnum       = time(s)
  39.  tmpname      = 'T:ms'tmpnum'.tmp'   /* The incoming mail file */
  40.  tmpdir       = 't:md'tmpnum'.tmp'   /* Temp DIR file */
  41.  tmpname2     = 't:mf'tmpnum'.tmp'   /* Various Temp files */
  42.  tmpuu        = 't:uu'tmpnum'.tmp'   /* temp uuencode file */
  43.  lockname     = 't:mailserver.lock'
  44.  req_from     = ''     /*  If Reply-To: then this holds requestor */
  45.  domain       = ''     /*  Only used if your sendmail             */
  46.  host         = ''     /*  needs them.                            */
  47.  publicdir    = 'pub:'
  48.  currentdir   = publicdir
  49.  sendmail     = 'sendmail -f $FROMUSER -t $TO < $MSG'
  50.  dirlevel     = 0
  51.  errornum     = 0
  52.  errormsg.1   = 'File / directory does not exist.'
  53.  errormsg.2   = 'Root directory has no parent.'
  54.  errormsg.3   = 'No such directory.'
  55.  
  56.  /* Copy stdin to temp file */
  57.  if (open(tmpfile, tmpname, 'w')) then do
  58.       do forever
  59.             line = readch(stdin, 64000)
  60.               /* Write to mail to temp file */
  61.                writech(tmpfile, Line)
  62.                if eof(stdin) then break
  63.       end
  64.     close(tmpfile)
  65.  end
  66.  
  67.  /* Wait for other copies of the program to finish */
  68.  
  69.  do while exists(lockname)
  70.      address command 'wait 3 secs'
  71.  end
  72.  
  73.  /* Open lock file to prevent other mailservers running */
  74.  
  75.  open(lockfile,lockname,"w")
  76.     writeln(lockfile,tmpname)
  77.  close(lockfile)
  78.  
  79. Return
  80.  
  81. /*********************************************************************/
  82.  
  83.   /* Get the mailbox name of the list owner */
  84.  
  85. get_listowner:
  86.  if inform = 'YES' then
  87.  do
  88.      /* Work out email address of mailserver owner */
  89.      open(tmpfile2,'ENV:username',"r")
  90.         username = readln(tmpfile2)
  91.      close(tmpfile2)
  92.      owner    = username
  93.  end
  94. return
  95.  
  96. /********************************************************************/
  97.  
  98. /* Who is the mail from? */
  99. who_from:
  100.  replyto =   ''
  101.  open(tmpfile,tmpname,"r")
  102.  /* read in first line of header (junk) */
  103.  line = (readln(tmpfile))
  104.  
  105.  do until (line='')
  106.      /* read a line of the file */
  107.      line = readln(tmpfile)
  108.      /*convert to upper case for testing*/
  109.      tst= upper(line)
  110.      if left(tst,5)= "FROM:" then req_from = right(line,length(line)-6)
  111.      if left(tst,5)= "FROM:" & replyto = '' then replyto = right(line,length(line)-6)
  112.      if left(tst,9)= "REPLY-TO:" then replyto = right(line,length(line)-10)
  113.  end
  114. return
  115.  
  116.  /* replyto now conatins return address */
  117.  
  118.  
  119. /********************************************************************/
  120.  
  121.  /* Send Confirmation slip */
  122.  
  123. send_receipt:
  124. if receipt = 'YES' then do
  125.      address command 'copy mailserver:sys/confirmation 'tmpname2
  126.               open(tmpfile2,tmpname2,"a")
  127.                   writeln(tmpfile2,line)
  128.                   writeln(tmpfile2,'')
  129.                   writeln(tmpfile2,'Requested by: 'req_from)
  130.               close(tmpfile2)
  131.     to = replyto
  132.     msg = tmpname2
  133.     call send_mail
  134.   end
  135. return
  136.  
  137. /********************************************************************/
  138.  
  139. process_instructions:
  140.   /* Now get instructions*/
  141.  
  142.  do until (eof(tmpfile)|line='--'|line='QUIT')
  143.  
  144.  errornum = 0
  145.  success  = 0
  146.  
  147.  line = readln(tmpfile)
  148.  
  149.  
  150.      /* Check for any external commands first */
  151.  
  152.      call check_externals
  153.  
  154.      line = upper(line)
  155.  
  156.      if (word(line,1)="DIR" | word(line,1)="LIST") then call dir
  157.  
  158.      if (word(line,1)="CD" | word(line,1)="CHDIR") then call cd
  159.      
  160.      if (word(line,1)="PARENT" | word(line,1)="CDUP") then call parent
  161.  
  162.      if word(line,1)="ROOT" then call root
  163.  
  164.      if word(line,1)= "HELP" then
  165.        do
  166.          /* Send HELP */
  167.        address command 'copy mailserver:sys/help 'tmpname2
  168.        to  = replyto
  169.        msg = tmpname2
  170.        call send_mail
  171.        end
  172.       if (word(line,1)="GET " | word(line,1)="SEND") then
  173.        do
  174.           /* Send a file */
  175.           file = word(line,2)
  176.           call check_get_dir
  177.  
  178.           /* Check that file exists  */
  179.           if exists(currentdir'/'file)=0 then 
  180.            do
  181.             errornum=1
  182.             call send_error
  183.            end
  184.           else
  185.  
  186.               /* Send the requested file */
  187.               if errornum = 0 then
  188.               do
  189.                /* First uuencode it if needed */
  190.                 do
  191.                  address command 'mailserver:sys/autoencode 'currentdir'/'file' 'tmpuu
  192.                  address command 'join mailserver:sys/headerfile 'tmpuu' as 'tmpname2
  193.                 end
  194.                 to = replyto
  195.                 msg = tmpname2
  196.                 call send_mail
  197.                end
  198.               end
  199.     end
  200.  close(tmpfile)
  201. return
  202.  
  203. /********************************************************************/
  204.  
  205. update_log:
  206.  
  207. if keeplog = 'YES' then
  208.  do
  209.   /* Put a separator line in the logfile */
  210.    open(logfile,logname, 'a')
  211.        writeln(logfile,'Date: 'date()'  'time())
  212.        writeln(logfile,'Request from: 'req_from)
  213.        writeln(logfile,'Reply to: 'replyto)
  214.        writeln(logfile,'')
  215.    close(logfile)
  216.   end
  217.  
  218.    /*Does owner want to be informed of mailserver access?*/
  219.    if inform = 'YES' then call inform_owner
  220.  
  221. return
  222.  
  223. /********************************************************************/
  224.  
  225. inform_owner:
  226.  do
  227.      /* Send a message to Mailserver owner */
  228.      address command 'join mailserver:sys/mailslip 'tmpname' as 'tmpname2
  229.      to  = owner
  230.      msg = tmpname2
  231.      call send_mail
  232.  end
  233. return
  234.  
  235. /********************************************************************/
  236.  
  237. clean_up:
  238.  /* Clean up */
  239.  address command 'delete >nil: 'tmpname
  240.  address command 'delete >nil: 'tmpname2
  241.  address command 'delete >nil: 'tmpdir
  242.  address command 'delete >nil: 'tmpuu
  243.  address command 'delete >nil: 'lockname
  244.  
  245. if exists('ENV:REALNAME') then
  246.     do
  247.      open(tmpfile2,'ENV:REALNAME',"w")
  248.         writeln(tmpfile2,realname)
  249.      close(tmpfile2)
  250.     end
  251.  
  252. return
  253.  
  254. /********************************************************************/
  255.  
  256. send_error:
  257.               /* send the error file */
  258.               address command 'copy mailserver:sys/headererror 'tmpname2
  259.               open(tmpfile2,tmpname2,"a")
  260.                   writeln(tmpfile2,line)
  261.                   writeln(tmpfile2,'')
  262.                   writeln(tmpfile2,errormsg.errornum)
  263.               close(tmpfile2)
  264.               to  = replyto
  265.               msg = tmpname2
  266.               call send_mail
  267. return
  268.  
  269. /********************************************************************/
  270.  
  271. check_get_dir:
  272. /* Check the format of directories in a GET command */
  273.  
  274. success = 1
  275. dir = ''
  276.  
  277. do chr = 1 to length(file)
  278.   temp = substr(file,chr,1)
  279.   temp2 = temp
  280.   if temp = '\' then temp2= ' '
  281.   if temp = '/' then temp2= ' '
  282.   dir = dir || temp2
  283. end
  284.  
  285. dir2 = ''
  286.  
  287. do wrd = 1 to words(dir)
  288. dir2 = dir2 || word(dir,wrd) || '/'
  289. end
  290.  
  291. /* Remove trailing '/' */
  292. file = left(dir2,length(dir2)-1)
  293.  
  294.  
  295. return
  296.  
  297. /********************************************************************/
  298.  
  299. dir:
  300. success = 1
  301.  /* Send directory listing */
  302.  
  303.  direc = ''
  304.  if word(line,2) ~= '' then
  305.    do
  306.    direc = word(line,2) /* optional directory */
  307.    dir = ''
  308.  
  309.   do chr = 1 to length(direc)
  310.     temp = substr(direc,chr,1)
  311.     temp2 = temp
  312.     if temp = '\' then temp2= ' '
  313.     if temp = '/' then temp2= ' '
  314.     dir = dir || temp2
  315.   end
  316.  
  317.   dir2 = ''
  318.  
  319.   do wrd = 1 to words(dir)
  320.    dir2 = dir2 || word(dir,wrd) || '/'
  321.   end
  322.  
  323.   /* Remove trailing '/' */
  324.   direc = left(dir2,length(dir2)-1)
  325.   end
  326.      
  327.   if right(currentdir,1) ~= ':' then direc = '/'direc
  328.  
  329.      address command dir_cmd' 'currentdir || direc' 'dir_cmd_opts' > 'tmpdir
  330.      address command 'join mailserver:sys/headerdir 'tmpdir' as 'tmpname2
  331.      to  = replyto
  332.      msg = tmpname2
  333.      call send_mail
  334. return
  335.  
  336. /********************************************************************/
  337.  
  338. cd:
  339. /* change directory */
  340.  
  341.  success = 1
  342.  direc = ''
  343.  if word(line,2) ~= '' then
  344.    do
  345.    direc = word(line,2) /* directory */
  346.    dir = ''
  347.  
  348.      do chr = 1 to length(direc)
  349.        temp = substr(direc,chr,1)
  350.        temp2 = temp
  351.        if temp = '\' then temp2= ' '
  352.        if temp = '/' then temp2= ' '
  353.        dir = dir || temp2
  354.      end
  355.  
  356.     dir2 = ''
  357.  
  358.   do wrd = 1 to words(dir)
  359.    dir2 = dir2 || word(dir,wrd) || '/'
  360.   end
  361.  
  362.   /* Remove trailing '/' */
  363.   direc = left(dir2,length(dir2)-1)
  364.  end
  365.  
  366.  /*direc now contains directory name or is empty */
  367.  
  368.   if right(currentdir,1) ~= ':' then direc = '/'direc
  369.  
  370.  
  371.   /* Does directory exist? */
  372.   if exists(currentdir || direc) = 0 then
  373.    do
  374.     errornum = 3
  375.     call send_error
  376.    end
  377.  
  378.   else
  379.    do
  380.      currentdir = currentdir || direc
  381.      dirlevel = dirlevel+words(dir)
  382.    end
  383. return
  384.  
  385. /********************************************************************/
  386.  
  387. parent:
  388.  success = 1
  389.  dir = currentdir
  390.  
  391.  if dirlevel = 0 then
  392.  do
  393.   /* command failed */
  394.   errornum = 2
  395.   call send_error
  396.  end
  397.  
  398.  else
  399.  
  400.   do
  401.   /* take the final '/xxx' out of the dir name */
  402.    dirlevel = dirlevel-1
  403.    temp = reverse(dir)
  404.    chrnum = verify(temp,'/','m')
  405.    dir =  right(temp,length(temp)-chrnum)
  406.    currentdir = reverse(dir)
  407.   end
  408. return
  409.  
  410. /********************************************************************/
  411.  
  412. root:
  413. success    = 1
  414. currentdir = publicdir
  415. dirlevel   = 0
  416.  
  417. return
  418.  
  419. /********************************************************************/
  420.  
  421. get_prefs:
  422.   if exists(prefsfile) =1 then
  423.     do
  424.      open(tmpfile2,prefsfile,'r')
  425.        do until eof(tmpfile2)
  426.         line = readln(tmpfile2)
  427.  
  428.         if ((line~='') & (left(line,1)~='#')) then
  429.           do
  430.           /* process keywords */
  431.           keyword = upper(word(line,1))
  432.           value   = upper(word(line,3))
  433.            if keyword = 'OWNER' then owner = value
  434.            if keyword = 'DOMAIN' then domain = value
  435.            if keyword = 'HOST' then host = value
  436.            if keyword = 'INFORM' then inform = value
  437.            if keyword = 'KEEPLOG' then keeplog = value
  438.            if keyword = 'LOGNAME' then logname = value
  439.            if keyword = 'RECEIPT' then receipt = value
  440.            if keyword = 'MAILNAME' then 
  441.            do
  442.             /* Mailname's value can be more than one word */
  443.              temp  = wordindex(line,3)
  444.              value = right(line,length(line)-temp+1)
  445.              mailname = value
  446.            end
  447.            if keyword = 'SENDMAIL' then
  448.            do
  449.             /* Sendmail's value can be more than one word */
  450.              temp  = wordindex(line,3)
  451.              value = right(line,length(line)-temp+1)
  452.              sendmail = value
  453.            end
  454.  
  455.            if keyword = 'DIR_CMD' then dir_cmd = value
  456.            if keyword = 'DIR_CMD_OPTS' then
  457.            do
  458.             /* dir_cmd_opts value can be more than one word */
  459.              temp  = wordindex(line,3)
  460.              value = right(line,length(line)-temp+1)
  461.              dir_cmd_opts = value
  462.            end
  463.  
  464.            if keyword = 'PUBLICDIR' then
  465.            do
  466.             publicdir  = value
  467.             currentdir = value
  468.            end
  469.           end
  470.        end
  471.      close(tmpfile2)
  472.     end
  473. return
  474.  
  475. /********************************************************************/
  476.  
  477. change_realname:
  478.  /* Try to find REALNAME env variable */
  479.  
  480. if exists('ENV:REALNAME') then
  481.     do
  482.      open(tmpfile2,'ENV:REALNAME',"r")
  483.         realname = readln(tmpfile2)
  484.      close(tmpfile2)
  485.     end
  486.  
  487. address command 'setenv REALNAME 'mailname
  488.  
  489. return
  490.  
  491. /********************************************************************/
  492.  
  493. /* Execute Amigados startup file if present */
  494. startup:
  495.  
  496. if exists('mailserver:sys/startup') then
  497.  do
  498.   address command 'execute >nil: mailserver:sys/startup'
  499.  end
  500.  
  501. return
  502.  
  503. /********************************************************************/
  504.  
  505. /* call your sendmail commad */
  506. send_mail:
  507.  
  508. string = sendmail ; search = '$FROMUSER' ; replace = 'mailserver'
  509. call substitute
  510.  
  511. string = temp ; search = '$FROMREAL' ; replace = mailname
  512. call substitute
  513.  
  514. string = temp ; search = '$MSG' ; replace = msg
  515. call substitute
  516.  
  517. string = temp ; search = '$FROMDOMAIN' ; replace = domain
  518. call substitute
  519.  
  520. string = temp ; search = '$FROMHOST' ; replace = host
  521. call substitute
  522.  
  523. /* Add the To: line at the top of the mail */
  524. address command 'rename 'msg' 'msg'.bak'
  525. open(t,msg,'w')
  526.  writeln(t,'To: 'to)
  527. close(t)
  528. address command "type "msg".bak >> "msg
  529.  
  530. /* Send the mail */
  531. address command temp
  532.  
  533. /* delete old copy of the message */
  534. address command 'delete >nil:  'msg'.bak'
  535.  
  536. return
  537.  
  538. /********************************************************************/
  539.  
  540. /* Replace on substring in a string with another */
  541. /* Needs 3 vaiarbles set, string,search,replace */
  542.  
  543. substitute:
  544. v = index(string,search)
  545.  if v > 1 then
  546.  do
  547.   lft = left(string,v-1)
  548.   rht = right(string,length(string)-length(search)-v+1)
  549.   str = lft || replace ||rht
  550.   temp = str
  551.  end
  552.  else temp = string
  553.  
  554. return
  555.  
  556. /********************************************************************/
  557.  
  558. /* Get external commands */
  559. get_externals:
  560.  
  561.  
  562.   if exists(externalsfile) =1 then
  563.     do
  564.      open(tmpfile2,externalsfile,'r')
  565.        do until eof(tmpfile2)
  566.         extline = readln(tmpfile2)
  567.  
  568.         if ((extline~='') & (left(extline,1)~='#')) then
  569.           do
  570.           /* process keywords */
  571.           numexternals = numexternals + 1
  572.           ext_keyword.numexternals = upper(word(extline,1))
  573.              temp  = wordindex(extline,2)
  574.             ext_cmd.numexternals = right(extline,length(extline)-temp+1)
  575.           end
  576.        end
  577.      close(tmpfile2)
  578.     end
  579. return
  580.  
  581. /********************************************************************/
  582.  
  583. check_externals:
  584.  
  585. do tempnum = 1 to numexternals
  586.  
  587. if upper(word(line,1)) = ext_keyword.tempnum then
  588.  do
  589.   /* Found an external command */
  590.   success = 1
  591.   /* Replace %s with command line */
  592.  
  593.   string = ext_cmd.tempnum ; search = '%s' 
  594.   temp2  = wordindex(line,2)
  595.   replace = right(line,length(line)-temp2+1)
  596.   call substitute
  597.  
  598.   string = temp
  599.   search = '$msg' ; replace = tmpname
  600.   call substitute
  601.  
  602.   cmd = temp
  603.  
  604.   /* Add subject: and blank line */
  605.    open(tmpfile2,tmpname2,'w')
  606.     writeln(tmpfile2,'Subject: Your Request: '""""line"""")
  607.     writeln(tmpfile2,'')
  608.    close(tmpfile2)
  609.  
  610.    address command cmd' >> 'tmpname2
  611.  
  612.   to  = replyto
  613.   msg = tmpname2
  614.   call send_mail
  615.  
  616.  end
  617.  
  618. end
  619.  
  620. return
  621.  
  622. /********************************************************************/
  623.  
  624.